﻿using AutoMapper;
using Core.SimpleTemp.Application.Common;
using Core.SimpleTemp.Application.YH;
using Core.SimpleTemp.Common;
using Core.SimpleTemp.Common.AutoMapperExtend;
using Core.SimpleTemp.Common.BaseLibrary;
using Core.SimpleTemp.Common.PagingQuery;
using Core.SimpleTemp.Entitys;
using Core.SimpleTemp.Repositories;
using Core.Toolkit.AutoMapperExtend.DataDictionary;
using Core.Toolkit.Common;
using Core.Toolkit.Core;
using Core.Toolkit.Core.Api;
using Core.Toolkit.Core.Application;
using Core.Toolkit.Core.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Core.SimpleTemp.Application
{
    [AutoDi()]
    [AutoDi(typeof(IConcurrentDataDicProvider))]

    public class YH_TypeAppService : BaseAppService<YH_TypeDto, YH_Type, YH_TypeRepository>, IConcurrentDataDicProvider
    {
        readonly ExcelHelp _excelHelp;
        readonly TempDirDiHelp _TempDirHelp;
        readonly UserIdentity _userIdentity;
        readonly YHService _yHService;
        readonly IHttpContextAccessor _accessor;
        readonly ComPareList _comPareList;
        public YH_TypeAppService(YH_TypeRepository repository, ExcelHelp excelHelp, ComPareList comPareList, TempDirDiHelp tempDirHelp, IDataDicHelp dataDicHelp,
         IHttpContextAccessor accessor, YHService yHService) : base(repository)
        {
            _excelHelp = excelHelp;
            _comPareList = comPareList;
            _TempDirHelp = tempDirHelp; 
            _userIdentity = accessor?.HttpContext?.User?.GetUserIdentity();
            _yHService = yHService;
            _accessor = accessor;
        }


        /// <summary>
        /// 生成查询信息
        /// </summary>
        /// <param name="pagingQueryModel"></param>
        /// <returns></returns>
        private LoadPageOffsetModel<YH_Type, YH_TypeDto> GetLoadPageOffsetMode(PagingModel<YH_TypeDto> pagingQueryModel)
        {
            var loadPageOffsetModel = this.GetLoadPageOffsetModel(pagingQueryModel);
            var baseQuery = _repository.QueryBase().AsNoTracking();
            //查询条件
            var where = this.CreateQRList();
            //.Add(nameof(YH_TypeDto.Level), "in")
            //.Add(nameof(YH_TypeDto.Focus), "in")
            //.Add(nameof(YH_TypeDto.Points), "in");

            //工厂处理
            if (_userIdentity.Headoffice)
                where.Add("CreateFactory", "="); //总部从查询条件取工厂id
            else
                where.Add("CreateFactory", "=", _userIdentity.Factory);

            var filterExpre = where.BuildeQR(pagingQueryModel.Model.ToEntity<YH_Type>());

            loadPageOffsetModel.QueryWhere = filterExpre;
            loadPageOffsetModel.BasqQuery = baseQuery;
            //排序
            loadPageOffsetModel.OrderList = new List<OrderModel>()
            {
                new OrderModel(){ IsDesc=false,PropertyName="CreateTime"}
            };
            //指定查询字段 
            loadPageOffsetModel.Selector = u => new YH_Type()
            {
                Id = u.Id,
                CreateFactory = u.CreateFactory,
                Type = u.Type,
                Remark = u.Remark
            };
            return loadPageOffsetModel;
        }
        /// <summary>
        /// 查询列表
        /// </summary>
        /// <param name="pagingQueryModel"></param>
        /// <returns></returns>
        public async Task<IPageModel<YH_TypeDto>> GetList(PagingModel<YH_TypeDto> pagingQueryModel)
        {
            var loadPageOffsetModel = GetLoadPageOffsetMode(pagingQueryModel);
            return await base.LoadPageOffsetAsync(loadPageOffsetModel);
        }
        /// <summary>
        /// Get
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<YH_TypeDto> GetForPCAsync(Guid id)
        {
            var baseQuery = _repository.QueryBase().AsNoTracking();



            var result = await GetAsync(id, baseQuery);
            return Mapper.Map<YH_TypeDto>(result);
        }

        /// <summary>
        /// 逻辑删除，继承自基础服务类物理删除方法并重写调用基础仓储类逻辑删除方法
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="autoSave"></param>
        /// <returns></returns>
        public override async Task DeleteBatchAsync(Guid[] ids, bool autoSave = true)
        {
            foreach (Guid item in ids)
            {
                //调用基础仓储类中的逻辑删除方法
                await _repository.DeleteLogicAsync(item);
            }
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="pagingQueryModel"></param>
        /// <returns></returns>
        public async Task<string> Export(PagingModel<YH_TypeDto> pagingQueryModel)
        {
            var loadPageOffsetModel = GetLoadPageOffsetMode(pagingQueryModel);
            var DataList = await this.ExportDataAsync(loadPageOffsetModel);
            var excelData = DataList.Select((model, index) => new
            {
                Num = index + 1,
                Num_title = "序号",

                model.Type,
                Type_title = "隐患分类",

                model.Remark,
                Remark_title = "备注"
            }).ToList();
            return _excelHelp.Create(excelData);
        }
        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="file"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<List<string>> ImportAsync(IFormFile file)
        {
            //当前用户工厂ID
            Guid userFactory = (Guid)_userIdentity.Factory;
            var extension = System.IO.Path.GetExtension(file.FileName);
            var filePath = _TempDirHelp.GetFilePath(extension);
            await Filehelp.WriteFileAsync(file.OpenReadStream(), filePath);

            var dataList = new List<YH_Type>();
            var errMsgList = new List<string>();
            var sysAreas = await _yHService.GetAreaByFactoryAsync();
            IWorkbook workbook = new XSSFWorkbook(filePath);
            try
            {
                var sheet = workbook.GetSheetAt(0);
                int rowCount = sheet.LastRowNum;
                //验证模板是否正确
                var first = sheet.GetRow(0);
                if (first.GetCell(1)?.ToString() != "隐患分类" ||
                    first.GetCell(2)?.ToString() != "备注"
                    )
                {
                    errMsgList.Add($"请确认模板是否正确!");
                }
                for (int i = 1; i <= rowCount; i++)
                {
                    var row = sheet.GetRow(i);
                    var entity = new YH_Type();
                    //entity.TypeID = Guid.Parse(data);
                    //0.要素特性 
                    if (string.IsNullOrWhiteSpace(row.GetCell(1)?.ToString()))
                        errMsgList.Add($"第{i}行，【隐患分类】列 不能为空！");
                    else
                        entity.Type = row.GetCell(1)?.ToString();


                    entity.Remark = row.GetCell(2)?.ToString();

                    entity.CreateFactory = userFactory;





                    dataList.Add(entity);
                }
            }
            catch (Exception ex)
            {
                //errMsgList.Add($"导入异常:" + ex.Message);
            }
            finally
            {
                workbook.Close();
            }
            if (errMsgList.Any())
                return errMsgList;
            await _repository.Set.AddRangeAsync(dataList);
            await _repository.SaveAsync();
            System.IO.File.Delete(filePath);
            return errMsgList;
        }

        #region 字典数据池热更新
        public const string DATA_DIC_KEY = "095036";


        /// <summary>
        /// 向热更新数据池添加初始数据
        /// 项目已启动调用此方法
        /// </summary>
        /// <param name="_dataDic"></param>
        /// <param name="_dataDicListByCategory"></param>
        public void LoadData(ConcurrentDictionary<string, string> _dataDic, ConcurrentDictionary<string, List<DataDicModel>> _dataDicListByCategory)
        {
            //仅初始化dataDic (用于ConcurrentKeyToValue标签)
            var userList = _repository.Set.Select(u => new { u.Id, u.Type }).ToList();
            foreach (var item in userList)
            {
                _dataDic[ConcurrentDataDicPool.CreateKey(DATA_DIC_KEY, item.Id.ToString())] = item.Type ?? "";
            }
            _dataDicListByCategory[DATA_DIC_KEY] = GetDicModelList();
        }

        private List<DataDicModel> GetDicModelList()
        {
            var userList = _repository.Set.OrderBy(a => a.CreateTime).Select(u => new { u.Id, u.Type }).ToList();
            List<DataDicModel> dataDicModelList = new List<DataDicModel>();
            foreach (var item in userList)
            {
                dataDicModelList.Add(new DataDicModel
                {
                    Category = DATA_DIC_KEY,
                    Key = item.Id.ToString(),
                    Value = item.Type
                });
            }
            return dataDicModelList;
        }

        /// <summary>
        /// 热更新DataDic池
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="Name"></param>
        private void UpdateDataDidcPoll(string userId, string Name)
        {
            var key = ConcurrentDataDicPool.CreateKey(DATA_DIC_KEY, userId.ToString());
            ConcurrentDataDicPool.UpdateDataDic(key, Name);
            ConcurrentDataDicPool.UpdateCategory(DATA_DIC_KEY, GetDicModelList());
        }
        #endregion

    }

}
